//
//  LcbCoderModel.m
//  Lcb
//
//  Created by Lcb on 2017/2/4.
//  Copyright © 2017年 lcb. All rights reserved.
//

#import "LcbCoderModel.h"
#import <objc/runtime.h>

@implementation LcbCoderModel

-(void)encodeWithCoder:(NSCoder *)aCoder
{
    Class cls = [self class];
    while (cls != [NSObject class]) {
        unsigned int numberOfIvars =0;
        Ivar* ivars = class_copyIvarList(cls, &numberOfIvars);
        for(const Ivar* p = ivars; p < ivars+numberOfIvars; p++){
            Ivar const ivar = *p;
            const char *type =ivar_getTypeEncoding(ivar);
            NSString * typestr = [NSString stringWithUTF8String:type];
            NSString *key = [NSString stringWithUTF8String:ivar_getName(ivar)];
            id value = [self valueForKey:key];
            if (value) {
                if ([typestr isEqualToString:@"@\"NSAttributedString\""]) {
                    break;
                }
                switch (type[0]) {
                    case _C_STRUCT_B: {
                        NSUInteger ivarSize =0;
                        NSUInteger ivarAlignment =0;
                        NSGetSizeAndAlignment(type, &ivarSize, &ivarAlignment);
#if ! __has_feature(objc_arc)
                        const char * varchar = (const char *)self + ivar_getOffset(ivar);
#else
                        const char * varchar = (const char*)(__bridge void*)self + ivar_getOffset(ivar);
#endif
                        NSData *data = [NSData dataWithBytes:varchar
                                                      length:ivarSize];
                        [aCoder encodeObject:data forKey:key];
                    }
                        break;
                    default:
                        [aCoder encodeObject:value forKey:key];
                        break;
                }
            }
        }
        free(ivars);
        cls = class_getSuperclass(cls);
    }
}

- (id)initWithCoder:(NSCoder *)aDecoder
{
    self = [super init];
    if (self) {
        Class cls = [self class];
        while (cls != [NSObject class]) {
            unsigned int numberOfIvars =0;
            Ivar* ivars = class_copyIvarList(cls, &numberOfIvars);
            for(const Ivar* p = ivars; p < ivars + numberOfIvars; p++){
                Ivar const ivar = *p;
                const char *type =ivar_getTypeEncoding(ivar);
                NSString * typestr = [NSString stringWithUTF8String:type];
                NSString *key = [NSString stringWithUTF8String:ivar_getName(ivar)];
                id value = [aDecoder decodeObjectForKey:key];
                if (value) {
                    if ([typestr isEqualToString:@"@\"NSAttributedString\""]) {
                        break;
                    }
                    switch (type[0]) {
                        case _C_STRUCT_B: {
                            NSUInteger ivarSize =0;
                            NSUInteger ivarAlignment =0;
                            NSGetSizeAndAlignment(type, &ivarSize, &ivarAlignment);
                            NSData *data = [aDecoder decodeObjectForKey:key];
#if ! __has_feature(objc_arc)
                            char *sourceIvarLocation = (char*)self + ivar_getOffset(ivar);
#else
                            char *sourceIvarLocation = (char*)(__bridge void*)self + ivar_getOffset(ivar);
#endif
                            [data getBytes:sourceIvarLocation length:ivarSize];
                        }
                            break;
                        default:
                            [self setValue:[aDecoder decodeObjectForKey:key]
                                    forKey:key];
                            break;
                    }
                }
            }
            free(ivars);
            cls = class_getSuperclass(cls);
        }
    }
    return self;
}
@end
